package com.denlaku.longan.service.impl;

import com.denlaku.longan.anno.RequiredTx;
import com.denlaku.longan.datac.DataSourcePool;
import com.denlaku.longan.datac.DbUtil;
import com.denlaku.longan.qo.DataOriginQuery;
import com.denlaku.longan.qo.Query;
import com.denlaku.longan.repository.DataOriginRepository;
import com.denlaku.longan.service.DataOriginService;
import com.denlaku.longan.util.SnowflakeUtils;
import com.denlaku.longan.vo.DataOrigin;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.util.List;

/**
 * @author tianx
 */
@Slf4j
@Service
public class DataOriginServiceImpl implements DataOriginService {
	private static final String DATA_SOURCE_TEST_1 = "1";

	@Autowired
	private DataOriginRepository dataOriginRepository;

	@Autowired
	private StringEncryptor stringEncryptor;

	@Override
	@RequiredTx
	public int add(DataOrigin dataOrigin) {
		encryptPassword(dataOrigin);
        dataOrigin.setId(SnowflakeUtils.nextId());
		return dataOriginRepository.add(dataOrigin);
	}

	@Override
	@RequiredTx
	public int update(DataOrigin dataOrigin) {
		DataSourcePool.remove(dataOrigin);
		encryptPassword(dataOrigin);
		return dataOriginRepository.update(dataOrigin);
	}

	private void encryptPassword(DataOrigin dataOrigin) {
		String password = dataOrigin.getPassword();
		if (StringUtils.isNotEmpty(password)) {
            dataOrigin.setPassword(stringEncryptor.encrypt(password));
		}
	}

	@Override
	@RequiredTx
	public int delete(Query query) {
		DataOrigin dataOrigin = get(query);
		DataSourcePool.remove(dataOrigin);
		return dataOriginRepository.delete(query);
	}

	@Override
	public boolean test(DataOrigin dataOrigin, String flag) {
		if (DATA_SOURCE_TEST_1.equals(flag)) {
			Long id = dataOrigin.getId();
            dataOrigin = this.get(Query.of(id));
			if (dataOrigin != null) {
				String password = getPassword(Query.of(id));
                dataOrigin.setPassword(password);
			} else {
				log.warn("cannot get data source by id {}", id);
			}
		}
		if (dataOrigin != null) {
			String driverClassName = dataOrigin.getDriverClassName();
			String username = dataOrigin.getUsername();
			String password = dataOrigin.getPassword();
			String url = dataOrigin.getUrl();
			Connection connection = DbUtil.getConnection(url, username, password, driverClassName);
            return connection != null;
		}
		return false;
	}

	@Override
	public List<DataOrigin> list(DataOriginQuery query) {
		return dataOriginRepository.list(query);
	}

	@Override
	public DataOrigin get(Query query) {
		return dataOriginRepository.get(query);
	}

	@Override
	public String getPassword(Query query) {
		String password = dataOriginRepository.getPassword(query);
		return stringEncryptor.decrypt(password);
	}

	@Override
	public void clearTag(Long tenantId, Long tagId) {
		dataOriginRepository.clearTag(tenantId, tagId);
	}

}
